package cn.zebra.dev.base.module.member.service;

import cn.zebra.dev.base.module.member.entity.BaseMember;

import java.util.Collection;
import java.util.List;

/**
 * 会员接口约束 用于固定传参格式<br/>
 * 适用于不同的Dao层<br/>
 * Mybatis(Plus)、Hibernate(JPA)
 *
 * @author runnable@sina.cn
 */
public interface BaseMemberService<T extends BaseMember> {

    /**
     * 根据用户手机号查询用户
     *
     * @param phone 用户手机号
     * @return 用户
     */
    T findMemberByPhone(String phone);

    /**
     * 根据用户id与图片路径来更新该用户头像
     *
     * @param memberId 用户id
     * @param imageUrl 图片路径
     * @return 成功返回true 失败返回false
     */
    Boolean updateMemberHeadPhoto(Long memberId, String imageUrl);

    /**
     * 根据用户id更新用户新用户名
     *
     * @param memberId    用户id
     * @param newUsername 新用户名
     * @return 成功返回true 失败返回false
     */
    Boolean updateMemberName(Long memberId, String newUsername);

    /**
     * 根据用户id更新性别
     *
     * @param memberId 用户id
     * @param sex      性别
     * @return 成功返回true 失败返回false
     */
    Boolean updateMemberSex(Long memberId, Integer sex);

    /**
     * 根据用户id更新常用地址
     *
     * @param memberId 用户id
     * @param address  常用地址
     * @return 成功返回true 失败返回false
     */
    Boolean updateMemberAddress(Long memberId, String address);

    /**
     * 根据用户id修改用户密码
     *
     * @param memberId    用户id
     * @param newPassword 新加密后密码
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberPassword(Long memberId, String newPassword);

    /**
     * 根据用户手机号修改用户密码
     *
     * @param phone       用户手机号
     * @param newPassword 新加密后密码
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberPassword(String phone, String newPassword);

    /**
     * 根据用户id修改邮箱
     *
     * @param memberId 用户id
     * @param newEmail 新Email
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberEmail(Long memberId, String newEmail);

    /**
     * 根据用户id修改手机号
     *
     * @param memberId 用户id
     * @param newPhone 新手机号
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberPhone(Long memberId, String newPhone);

    /**
     * 根据用户id修改用户密码
     *
     * @param memberId             用户id
     * @param newSecondaryPassword 新加密后二级(交易)密码
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberSecondaryPassword(Long memberId, String newSecondaryPassword);

    /**
     * 根据用户id修改用户资金密码
     *
     * @param memberId             用户id
     * @param newSecondaryPassword 新加密后二级(交易)密码
     * @return 修改成功返回 true 失败返回false
     */
    Boolean updateMemberSecondaryPassword(Long memberId, String secondarySale, String newSecondaryPassword);

    /**
     * 根据用户id统计直推人数
     *
     * @param memberId 用户id
     * @return 直推人数
     */
    Integer countMemberByParentId(Long memberId);

    /**
     * 修改会员年龄
     *
     * @param memberId 用户id
     * @param age      新修改年龄
     * @return 成功返回True 失败返回False
     */
    Boolean updateMemberAge(Long memberId, Integer age);

    /**
     * 根据用户id查找用户信息
     *
     * @param memberId 用户id
     * @return 用户信息
     */
    default T findById(String memberId) {
        return this.findById(Long.valueOf(memberId));
    }

    /**
     * 根据用户id查找用户信息
     *
     * @param memberId 用户id
     * @return 用户信息
     */
    T findById(Long memberId);

    /**
     * 根据上级id 查询用户id与用户名列表
     *
     * @param parentId 上级用户id
     * @return 用户id与用户名列表
     */
    List<T> findIdAndMemberNameListByParentId(Long parentId);

    /**
     * 根据上级parent_id的上级parent_id查找用户id与用户名列表
     *
     * @param parentId 上级parentId
     * @return 用户id与用户名列表
     */
    List<T> findIdAndMemberNameListByParentIdOfParentId(Long parentId);

    /**
     * 用户等级升级 (以用户旧等级作为乐观锁)
     *
     * @param memberId       用户id
     * @param memberLevel    旧用户等级
     * @param newMemberLevel 新用户等级
     * @return 修改成功返回True 失败返回False
     */
    Boolean updateMemberLevel(Long memberId, Long memberLevel, Long newMemberLevel);

    /**
     * 用户经验值增加
     *
     * @param memberId 用户id
     * @param addExp   增加的经验值
     * @return 增加成功返回 True 失败返回False
     */
    Boolean addMemberExp(Long memberId, Long addExp);

    /**
     * 用户经验修改 (以旧用户经验值作为乐观锁)
     *
     * @param memberId 用户id
     * @param exp      旧用户经验值
     * @param newExp   新用户经验值
     * @return 修改成功返回 True 失败返回False
     */
    Boolean updateMemberExp(Long memberId, Long exp, Long newExp);

    /**
     * 根据用户id查找用户团队人数 (除自己)
     *
     * @param memberId 用户id
     * @return 团队人数
     */
    Long findTeamNumById(Long memberId);

    /**
     * 根据parent_id查找所有用户
     *
     * @param parentId 上级用户id
     * @return 下级用户信息集合
     */
    List<T> findListByParentId(Long parentId);

    /**
     * 根据parent_id与用户level查找所有用户
     *
     * @param parentId 上级用户id
     * @param levelId  用户等级
     * @return 用户信息集合
     */
    List<T> findListByParentIdAndMemberLevel(Long parentId, Long levelId);

    /**
     * 根据上级parent_id的上级parent_id与等级id查找用户列表
     *
     * @param parentId 上级parentId
     * @return 用户id与用户名列表
     */
    List<T> findIdAndMemberNameListByParentIdOfParentIdAndLevelId(Long parentId, Long levelId);

    /**
     * 获取今日注册用户量
     *
     * @return 今日注册用户
     */
    Long findCurDateCountMember();

    /**
     * 获取用户量
     *
     * @return 用户量
     */
    Long findTotalMember();

    /**
     * 修改用户盐
     *
     * @param memberId 用户id
     * @param salt     盐
     * @return 成功返回True 失败返回False
     */
    Boolean updateMemberSalt(Long memberId, String salt);

    /**
     * 修改用户交易盐
     *
     * @param memberId 用户id
     * @param salt     盐
     * @return 成功返回True 失败返回False
     */
    Boolean updateMemberSecondarySalt(Long memberId, String salt);

    /**
     * 根据多个用户id查找用户信息集合
     *
     * @param memberIds 用户id集合
     * @return 用户信息集合
     */
    Collection<T> findListByMemberIds(Collection<Long> memberIds);

    /**
     * 根据用户名查找用户信息
     *
     * @param memberName 用户名
     * @return 用户对象
     */
    BaseMember findByMemberName(String memberName);

    /**
     * 根据用户id修改用户状态
     *
     * @param memberId 用户id
     * @param status   要修改成的状态
     * @return 修改成功返回true 失败返回false
     */
    Boolean updateStatus(Long memberId, Integer status);
}
